package com.eternal.settings;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.callback.NavCallback;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.concat.BluetoothEvent;
import com.eternal.base.concat.DeviceModel;
import com.eternal.base.concat.DeviceName;
import com.eternal.base.concat.DeviceSetting;
import com.eternal.base.data.DeviceRepository;
import com.eternal.base.data.RepositoryInjection;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.global.ProgressEvent;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.binding.command.BindingCommand;
import com.eternal.framework.bus.Messenger;
import com.eternal.framework.bus.RxBus;
import com.eternal.framework.component.AppManager;
import com.eternal.framework.component.BaseViewModel;
import com.eternal.framework.utils.KLog;
import com.eternal.framework.utils.RxUtils;
import com.eternal.framework.utils.ToastUtils;
import com.eternal.framework.utils.Utils;
import com.eternal.widget.guqiang.ProgressToolbar;

import io.reactivex.Completable;
import io.reactivex.CompletableEmitter;
import io.reactivex.CompletableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by Administrator
 * On 2020/4/30
 * Description:
 *
 * @author Administrator
 */
public class SettingModel extends BaseViewModel {
    private String mac;
    private DeviceRepository repository;
    private Disposable subs, localSubs, timeEvent, nameRefresh;
    private boolean connected;
    private byte type, port;

    public byte transTmp;
    public byte transHum;
    public byte caliTmp;
    public byte caliHum;
    public byte brightness;

    public MutableLiveData<String> deviceName = new MutableLiveData<>();
    public MutableLiveData<String> name = new MutableLiveData<>();
    public MutableLiveData<Boolean> isEdit = new MutableLiveData<>();
    public MutableLiveData<String> edit = new MutableLiveData<>();
    public MutableLiveData<String> time = new MutableLiveData<>();
    public MutableLiveData<Boolean> isDegree = new MutableLiveData<>();
    public MutableLiveData<Integer> tmpRes = new MutableLiveData<>();
    public MutableLiveData<Integer> timeColor = new MutableLiveData<>();
    public MutableLiveData<Integer> progress = new MutableLiveData<>();
    public MutableLiveData<String> subtitle = new MutableLiveData<>();

    public SettingModel(@NonNull Application application) {
        super(application);
        isEdit.setValue(true);
        edit.setValue(Utils.getString(R.string.tip_edit));
        tmpRes.setValue(R.mipmap.group_c);
    }

    void init(DeviceRepository repository, String mac, byte port, String timeStr, byte type) {
        this.repository = repository;
        if (RepositoryInjection.providerDeviceRepository().isConnect(mac)) {
            connected = true;
            timeColor.setValue(ContextCompat.getColor(Utils.getContext(), android.R.color.white));
            time.setValue(Utils.getString(R.string.tip_connect,
                    ProtocolTransformer.getTime(System.currentTimeMillis())));
            registerEvent();
        } else {
            connected = false;
            timeColor.setValue(ContextCompat.getColor(Utils.getContext(), R.color.color_FF2D55));
            if (TextUtils.isEmpty(timeStr)) {
                timeStr = repository.getTime(mac);
            }
            time.setValue(timeStr);
        }
        if (port == 0) {
            name.setValue(Utils.getString(R.string.setting_device_name));
        } else {
            name.setValue(Utils.getString(R.string.setting_port_name));
        }
        connectEvent();
        this.type = type;
        this.mac = mac;
        this.port = port;
        initData();
        refreshData();
        refreshName();
    }

    @SuppressLint("CheckResult")
    private void refreshName() {
        if (nameRefresh == null || nameRefresh.isDisposed()) {
            nameRefresh = RepositoryInjection.providerDeviceRepository()
                    .getDeviceName(mac, port)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DeviceName>() {
                        @Override
                        public void accept(DeviceName deviceName) {
                            if (deviceName != null) {
                                subtitle.setValue(deviceName.name);
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) {
                            KLog.e(throwable);
                        }
                    });
            addSubscribe(localSubs);
        }
    }

    private void connectEvent() {
        addSubscribe(RxBus.getDefault().toObservable(BluetoothEvent.class).subscribe(new Consumer<BluetoothEvent>() {
            @Override
            public void accept(BluetoothEvent event) {
                if (event.what == BluetoothEvent.DISCONNECT && mac.equals(event.obj)) {
                    addSubscribe(Completable.create(new CompletableOnSubscribe() {
                        @Override
                        public void subscribe(CompletableEmitter emitter) throws Exception {
                            String timeStr = Utils.getString(R.string.tip_last,
                                    ProtocolTransformer.getTime(System.currentTimeMillis()));
                            time.setValue(timeStr);
                            timeColor.setValue(ContextCompat.getColor(Utils.getContext(), R.color.color_FF2D55));
                        }
                    }).subscribeOn(AndroidSchedulers.mainThread()).subscribe());
                    connected = false;
                    unregisterRxBus();
                } else if (event.what == BluetoothEvent.CONNECT && mac.equals(event.obj)) {
                    timeColor.setValue(ContextCompat.getColor(Utils.getContext(), android.R.color.white));
                    time.setValue(Utils.getString(R.string.tip_connect,
                            ProtocolTransformer.getTime(System.currentTimeMillis())));
                    connected = true;
                    registerEvent();
                    refreshData();
                }
            }
        }));
    }

    @Override
    public void unregisterRxBus() {
        if (timeEvent != null) {
            timeEvent.dispose();
            timeEvent = null;
        }
    }

    @SuppressLint("CheckResult")
    private void initData() {
        // 从本地获取
        localSubs = repository.getSetting(mac, port, type, true)
                .compose(RxUtils.<DeviceSetting>bindToLifecycle(getLifecycleProvider()))
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) {
//                        if (connected) {
//                            RxBus.getDefault().post(new ProgressEvent(ProgressEvent.START));
//                        }
                    }
                })
                .subscribe(new Consumer<DeviceSetting>() {
                    @Override
                    public void accept(DeviceSetting setting) {
                        isDegree.setValue(!setting.isDegree);
                        onTmp.execute();
                        deviceName.setValue(setting.name);
                        Messenger messenger = Messenger.getDefault();
                        messenger.send(setting.brightness, SettingActivity.SET_BRIGHTNESS);
                        messenger.send(setting.transitionTemperature, SettingActivity.SET_TRANS_TMP);
                        messenger.send(setting.transitionHumidity, SettingActivity.SET_TRANS_HUM);
                        messenger.send(setting.calibrationTemperature, SettingActivity.SET_CALI_TMP);
                        messenger.send(setting.calibrationHumidity, SettingActivity.SET_CALI_HUM);
//                        if (connected) {
//                            RxBus.getDefault().post(new ProgressEvent(ProgressEvent.END));
//                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) {
//                        throwable.printStackTrace();
                        KLog.e(throwable);
                    }
                });
        addSubscribe(localSubs);
    }

    @SuppressLint("CheckResult")
    private void refreshData() {
        subs = repository.getSetting(mac, port, type, false)
                .compose(RxUtils.<DeviceSetting>bindToLifecycle(getLifecycleProvider()))
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) {
                        if (connected) {
                            RxBus.getDefault().post(new ProgressEvent(ProgressEvent.START));
                        }
                    }
                })
                .subscribe(new Consumer<DeviceSetting>() {
                    @Override
                    public void accept(DeviceSetting setting) {
                        isDegree.setValue(!setting.isDegree);
                        onTmp.execute();
                        deviceName.setValue(setting.name);
                        Messenger messenger = Messenger.getDefault();
                        messenger.send(setting.brightness, SettingActivity.SET_BRIGHTNESS);
                        messenger.send(setting.transitionTemperature, SettingActivity.SET_TRANS_TMP);
                        messenger.send(setting.transitionHumidity, SettingActivity.SET_TRANS_HUM);
                        messenger.send(setting.calibrationTemperature, SettingActivity.SET_CALI_TMP);
                        messenger.send(setting.calibrationHumidity, SettingActivity.SET_CALI_HUM);
                        if (connected) {
                            RxBus.getDefault().post(new ProgressEvent(ProgressEvent.END));
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) {
//                        throwable.printStackTrace();
                        KLog.e(throwable);
                    }
                });
        addSubscribe(subs);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private void updateTime() {
        if (repository.isConnect(mac)) {
            time.setValue(Utils.getString(R.string.tip_connect,
                    ProtocolTransformer.getTime(System.currentTimeMillis())));
        }
    }

    private void registerEvent() {
        if (timeEvent == null || timeEvent.isDisposed()) {
            RxBus bus = RxBus.getDefault();
            timeEvent = bus.toObservable(Long.class)
                    .compose(RxUtils.<Long>bindToLifecycle(getLifecycleProvider()))
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long time) {
                            SettingModel.this.time.setValue(Utils.getString(R.string.tip_connect,
                                    ProtocolTransformer.getTime(time)));
                        }
                    });
        }
    }

    public BindingCommand<Void> onEdit = new BindingCommand<>(new BindingAction() {
        @Override
        public void call() {
            if (isEdit.getValue() == Boolean.TRUE) {
                edit.setValue(Utils.getString(R.string.tip_ok));
                isEdit.setValue(false);
            } else {
                edit.setValue(Utils.getString(R.string.tip_edit));
                isEdit.setValue(true);
            }
        }
    });

    public BindingCommand<Void> onTmp = new BindingCommand<>(new BindingAction() {
        @Override
        public void call() {
            if (isDegree.getValue() == Boolean.TRUE) {
                isDegree.setValue(false);
                tmpRes.setValue(R.mipmap.group_f);
            } else {
                isDegree.setValue(true);
                tmpRes.setValue(R.mipmap.group_c);
            }
        }
    });

    public BindingCommand<Void> onConfirm = new BindingCommand<>(new BindingAction() {
        @SuppressLint("CheckResult")
        @Override
        public void call() {
            if (connected) {
                if (TextUtils.isEmpty(deviceName.getValue())) {
                    showEmptyDialog();
                    return;
                }
                DeviceSetting setting = new DeviceSetting();
                setting.isDegree = isDegree.getValue();
                setting.name = deviceName.getValue();
                setting.brightness = brightness;
                setting.transitionTemperature = transTmp;
                setting.transitionHumidity = transHum;
                setting.calibrationTemperature = caliTmp;
                setting.calibrationHumidity = caliHum;
                repository.setSetting(mac, port, type, setting)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .compose(RxUtils.<Boolean>bindToLifecycle(getLifecycleProvider()))
                        .doOnSubscribe(new Consumer<Disposable>() {
                            @Override
                            public void accept(Disposable disposable) throws Exception {
                                RxBus.getDefault().post(new ProgressEvent(ProgressEvent.START));
                            }
                        })
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(final Boolean result) {
                                RxBus.getDefault().post(new ProgressEvent(new ProgressToolbar.Callback() {
                                    @Override
                                    public void onEnd() {
                                        if (!result) {
                                            ToastUtils.showShort("setting set failed!");
                                        } else {
                                            repository.getModel(mac, port).subscribeOn(Schedulers.io())
                                                    .subscribe(new Consumer<DeviceModel>() {
                                                        @Override
                                                        public void accept(DeviceModel model) throws Exception {
                                                            RxBus.getDefault().post(new ActivityEvent(ActivityEvent.SET_DEVICE_MODEL_INFO_DEGREE, model));
                                                            RxBus.getDefault().post(System.currentTimeMillis());
                                                            onBack.execute();
                                                        }
                                                    });
//                                            if(type<3){
//
//                                            }else{
//                                                onBack.execute();
//                                            }
                                        }
                                    }
                                }));
                            }
                        }, new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) {
                                RxBus.getDefault().post(new ProgressEvent(ProgressEvent.END));
//                                throwable.printStackTrace();
                                KLog.e(throwable);
                            }
                        });
            }
        }
    });

    public BindingCommand<Void> onCancel = new BindingCommand<>(new BindingAction() {
        @Override
        public void call() {
//            subs = repository.getSetting(mac)
//                    .compose(RxUtils.<DeviceSetting>bindToLifecycle(getLifecycleProvider()))
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Consumer<DeviceSetting>() {
//                        @Override
//                        public void accept(DeviceSetting setting) {
//                            isDegree.setValue(!setting.isDegree);
//                            onTmp.execute();
//                            deviceName.setValue(setting.name);
//                            Messenger messenger = Messenger.getDefault();
//                            messenger.send(setting.brightness, SettingActivity.SET_BRIGHTNESS);
//                            messenger.send(setting.transitionTemperature, SettingActivity.SET_TRANS_TMP);
//                            messenger.send(setting.transitionHumidity, SettingActivity.SET_TRANS_HUM);
//                            messenger.send(setting.calibrationTemperature, SettingActivity.SET_CALI_TMP);
//                            messenger.send(setting.calibrationHumidity, SettingActivity.SET_CALI_HUM);
//                            subs.dispose();
//                        }
//                    }, new Consumer<Throwable>() {
//                        @Override
//                        public void accept(Throwable throwable) {
//                            throwable.printStackTrace();
//                            KLog.e(throwable);
//                        }
//                    });
            onBack.execute();
        }
    });

    public BindingCommand<Void> onBack = new BindingCommand<>(new BindingAction() {
        @Override
        public void call() {
            ARouter.getInstance().build(RouterActivityPath.Detail.PAGE_DETAIL)
                    .withTransition(R.anim.left_in, R.anim.right_out)
                    .navigation(AppManager.getAppManager().currentActivity(), new NavCallback() {
                        @Override
                        public void onArrival(Postcard postcard) {
                            finish();
                        }
                    });
        }
    });

    public BindingCommand<Void> onDelete = new BindingCommand<>(new BindingAction() {
        @Override
        public void call() {
            final Activity activity = AppManager.getAppManager().currentActivity();
            View view = activity.getLayoutInflater().inflate(R.layout.reconfirm_dialog, null, false);
            final MaterialDialog dialog = new MaterialDialog.Builder(activity)
                    .backgroundColor(0x00ffffff)
                    .customView(view, false)
                    .build();
            dialog.show();
            view.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });
            view.findViewById(R.id.tv_confirm).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                    Class<?> c = ARouter.getInstance().build(RouterActivityPath.Detail.PAGE_DETAIL).getDestination();
                    AppManager.getAppManager().finishActivity(c);
                    ARouter.getInstance().build(RouterActivityPath.Main.PAGE_MAIN)
                            .withTransition(R.anim.left_in, R.anim.right_out)
                            .withString(ActivityEvent.DEVICE_MAC, mac)
                            .withAction(ActivityEvent.ACTION_DELETE_DEVICE)
                            .navigation(activity, new NavCallback() {
                                @Override
                                public void onArrival(Postcard postcard) {
                                    finish();
                                }
                            });
                }
            });
        }
    });

    public void showEmptyDialog() {
        final Activity activity = AppManager.getAppManager().currentActivity();
        View view = activity.getLayoutInflater().inflate(R.layout.dialog_tip_ok, null, false);
        TextView content = view.findViewById(R.id.tv_content);
        content.setText("The name cannot be empty.");
        MaterialDialog.Builder builder = new MaterialDialog.Builder(activity)
                .customView(view, false);

        if (builder != null) {
            builder.backgroundColor(0x00ffffff);
            final MaterialDialog dialog = builder.build();
            view.findViewById(R.id.tv_confirm).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });
            dialog.show();
        }
    }
}
